home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Online
/
SpeakFreely
/
src
/
soundbyte.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-18
|
7KB
|
306 lines
/*
Sound interface for Speak Freely for Unix
Designed and implemented in July of 1990 by John Walker
*/
#include "speakfree.h"
#include <stdio.h>
#include <fcntl.h>
#ifdef AUDIO_DEVICE_FILE
#include <errno.h>
#include <sys/ioctl.h>
#define AUDIO_MIN_GAIN 0
#define AUDIO_MAX_GAIN 255
static int abuf_size;
#ifdef IN_AUDIO_DEV
#define SoundFileIn IN_AUDIO_DEV
#else
#define SoundFileIn "/dev/audio"
#endif
#ifdef OUT_AUDIO_DEV
#define SoundFileOut OUT_AUDIO_DEV
#else
#define SoundFileOut "/dev/audio"
#endif
#ifdef sun
#define AUDIO_CTLDEV "/dev/audioctl"
#else
#define AUDIO_CTLDEV "/dev/mixer"
#endif
char *devAudioInput = SoundFileIn, /* Audio device files to open. */
*devAudioOutput = SoundFileOut, /* These can overridden by the -y */
*devAudioControl = AUDIO_CTLDEV; /* option on sfmike and sfspeaker. */
#define MAX_GAIN 100
struct sound_buf {
struct sound_buf *snext; /* Next sound buffer */
int sblen; /* Length of this sound buffer */
unsigned char sbtext[2]; /* Actual sampled sound */
};
/* Local variables */
static int paudiof = -1; /* For playing */
static int raudiof = -1; /* For recording */
static int mode = -1;
static int volume = 100;
static char WriteFile[256]; /* For the template */
static char ReadFile[256]; /* For the template */
static short pbuf[BUFL]; /* Buffer for playing */
static short rbuf[BUFL];
static int audiof = -1; /* Audio device file descriptor */
static int Audio_fd; /* Audio control port */
#ifdef sun
static audio_info_t Audio_info; /* Current configuration info */
#endif
struct sound_buf *sbchain = NULL, /* Sound buffer chain links */
*sbtail = NULL;
static int sbtotal = 0; /* Total sample bytes in memory */
static int playing = FALSE; /* Replay in progress ? */
/* static int playqsize; */ /* Output queue size */
static int playlen = 0; /* Length left to play */
static unsigned char *playbuf= NULL; /* Current play pointer */
static int squelch = 0; /* Squelch value */
extern int neverRelease = FALSE; /* Never release audio device. This
is set if we inherited our open
audio device file descriptor from
a parent process. If we release
it, there's no way we can get it
back, so we glom onto it until
we exit. */
/* Convert local gain into device parameters */
static unsigned scale_gain(g)
unsigned g;
{
return (AUDIO_MIN_GAIN + (unsigned)
((int) ((((double) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) *
((double) g / (double) MAX_GAIN)) + 0.5)));
}
#ifdef Solaris
/* SETAUBUFSIZE -- Preset size of internal /dev/audio buffer segments
Must be called before soundinit() */
static int aubufsize = 2048; /* Default */
void setaubufsize(size)
int size;
{
aubufsize = size;
}
#endif
/* SOUNDINIT -- Open the sound peripheral and initialise for
access. Return TRUE if successful, FALSE
otherwise. */
int soundinit(iomode)
int iomode;
{
char *variable;
int punit = 0;
int runit = 0;
/* Save mode for soundplayvol() */
mode = iomode;
if(iomode == -1) {
return FALSE;
}
/* Find out where to read and play audio */
variable = getenv("SPEAKFREE_PLAY_UNIT");
if(variable) {
punit = strtol(variable, NULL, 10);
}
variable = getenv("SPEAKFREE_RECORD_UNIT");
if(variable) {
runit = strtol(variable, NULL, 10);
}
sprintf((char *) WriteFile,
"AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
"VOLUME/%d/BUFFER/8192/UNIT/%d", volume, punit);
sprintf((char *) ReadFile,
"AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
"BUFFER/2048/UNIT/%d", runit);
if (iomode != O_RDONLY) {
if ((paudiof = open(WriteFile, O_WRONLY)) < 0) {
fprintf(stderr, "Audio open: unable to open \"%s\"\n", WriteFile);
return FALSE;
}
}
if (iomode != O_WRONLY) {
if ((raudiof = open(ReadFile, O_RDONLY)) < 0) {
fprintf(stderr, "Audio open: unable to open \"%s\"\n", ReadFile);
return FALSE;
}
}
return TRUE;
}
/* SOUNDTERM -- Close the sound device. */
void soundterm()
{
if (paudiof >= 0) {
if (close(paudiof) < 0) {
perror("closing audio device");
}
paudiof = -1;
}
if (raudiof >= 0) {
if (close(raudiof) < 0) {
perror("closing audio device");
}
raudiof = -1;
}
mode = -1;
}
/* SOUND_OPEN_FILE_DESCRIPTORS -- Obtain file descriptors of open
audio and audio control device files. */
void sound_open_file_descriptors(audio_io, audio_ctl)
int *audio_io, *audio_ctl;
{
*audio_io = audiof;
*audio_ctl = Audio_fd;
}
/* SOUNDPLAY -- Begin playing a sound. */
void soundplay(len, buf)
int len;
unsigned char *buf;
{
int ios;
int i;
if(len > BUFL) {
len = BUFL;
}
/* Convert µlaw to 16 bit */
for (i = 0; i < len; i++) {
pbuf[i] = ulaw2linear(buf[i]);
}
while (TRUE) {
ios = write(paudiof, pbuf, len << 1 );
if (ios == -1) {
sf_usleep(100000);
} else {
ios >>= 1;
if (ios < len ) {
buf += ios;
len -= ios;
} else {
break;
}
}
}
}
/* SOUNDPLAYVOL -- Set playback volume from 0 (silence) to 100 (full on). */
void soundplayvol(value)
int value;
{
volume = value;
soundterm();
soundinit(mode);
}
/* SOUNDRECGAIN -- Set recording gain from 0 (minimum) to 100 (maximum). */
void soundrecgain(value)
int value;
{
}
/* SOUNDDEST -- Set destination for generated sound. If "where"
is 0, sound goes to the built-in speaker; if
1, to the audio output jack. */
void sounddest(where)
int where;
{
}
/* SOUNDGRAB -- Return audio information in the record queue. */
int soundgrab(buf, len)
char *buf;
int len;
{
long read_size;
int c;
int i;
if(len > BUFL) {
len = BUFL;
}
read_size = len;
while (TRUE) {
c = read(raudiof, rbuf, read_size << 1);
if (c < 0) {
if (errno == EINTR) {
continue;
}
} else {
c >>= 1;
}
break;
}
if (c < 0) {
perror("soundgrab");
}
/* Convert 16 bit to µlaw */
for (i = 0; i < len; i++) {
buf[i] = linear2ulaw(rbuf[i]);
}
return c;
}
/* SOUNDFLUSH -- Flush any queued sound. */
void soundflush()
{
/*
soundterm();
soundinit(mode);
*/
}
#endif /* AUDIO_DEVICE_FILE */